<template>
    <div class="bg-white rounded-lg">
        <div class="p-4 border-b">
            <h3 class="text-lg font-medium">权限配置</h3>
        </div>
        <div class="p-6">
            <PermissionTree :nodes="permissions" @update:checked="handlePermissionUpdate" />
        </div>
    </div>
</template>

<script setup lang="ts">
import { reactive, defineComponent, computed } from 'vue'

interface PermissionNode {
    id: number
    name: string
    type: number
    children?: PermissionNode[]
    checked: boolean
    indeterminate?: boolean
}

// 递归组件
const PermissionTree = defineComponent({
    name: 'PermissionTree',
    props: {
        nodes: {
            type: Array as () => PermissionNode[],
            required: true
        }
    },
    emits: ['update:checked'],
    setup(props, { emit }) {
        // 检查节点是否有子节点
        const hasChildren = (node: PermissionNode) => node.children && node.children.length > 0

        // 检查节点是否为操作类型
        const isAction = (node: PermissionNode) => node.type === 3

        // 处理节点选中状态变化
        const handleCheck = (node: PermissionNode) => {
            // 切换当前节点状态
            node.checked = !node.checked
            node.indeterminate = false
            
            // 更新子节点状态
            if (hasChildren(node)) {
                node.children!.forEach(child => {
                    child.checked = node.checked
                    child.indeterminate = false
                    if (hasChildren(child)) {
                        updateChildrenState(child)
                    }
                })
            }
            
            // 更新父节点状态
            updateParentState(props.nodes)
            
            // 触发更新事件
            emit('update:checked', node)
        }

        // 更新子节点状态
        const updateChildrenState = (node: PermissionNode) => {
            if (hasChildren(node)) {
                node.children!.forEach(child => {
                    child.checked = node.checked
                    child.indeterminate = false
                    if (hasChildren(child)) {
                        updateChildrenState(child)
                    }
                })
            }
        }

        // 更新父节点状态
        const updateParentState = (nodes: PermissionNode[]) => {
            nodes.forEach(node => {
                if (hasChildren(node)) {
                    const children = node.children!
                    const checkedCount = children.filter(c => c.checked).length
                    const indeterminateCount = children.filter(c => c.indeterminate).length
                    
                    node.checked = checkedCount === children.length
                    node.indeterminate = checkedCount > 0 && checkedCount < children.length || indeterminateCount > 0
                }
            })
        }

        return {
            hasChildren,
            isAction,
            handleCheck
        }
    },
    template: `
        <div class="space-y-4">
            <template v-for="node in nodes" :key="node.id">
                <!-- 模块/页面节点 -->
                <div v-if="!isAction(node)" class="space-y-2">
                    <div class="flex items-center py-1.5 hover:bg-gray-50 rounded">
                        <div class="flex items-center">
                            <div 
                                class="w-4 h-4 border rounded cursor-pointer relative"
                                :class="{
                                    'border-primary bg-primary': node.checked,
                                    'border-gray-300': !node.checked,
                                    'bg-indeterminate': node.indeterminate
                                }"
                                @click.stop="handleCheck(node)"
                            >
                                <svg v-if="node.checked && !node.indeterminate" class="w-3 h-3 text-white absolute top-0.5 left-0.5" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                                    <path d="M13.5 4.5L6.5 11.5L2.5 7.5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                </svg>
                            </div>
                            <span class="ml-2 font-medium" :class="{
                                'text-gray-900': !node.checked,
                                'text-primary': node.checked
                            }">{{ node.name }}</span>
                        </div>
                    </div>

                    <!-- 子节点容器 -->
                    <div v-if="hasChildren(node)" class="pl-6">
                        <!-- 操作按钮组 -->
                        <div v-if="node.children?.every(child => isAction(child))" 
                             class="flex flex-wrap gap-x-6 gap-y-2">
                            <div v-for="action in node.children" 
                                 :key="action.id" 
                                 class="flex items-center">
                                <div 
                                    class="w-4 h-4 border rounded cursor-pointer relative"
                                    :class="{
                                        'border-primary bg-primary': action.checked,
                                        'border-gray-300': !action.checked
                                    }"
                                    @click.stop="handleCheck(action)"
                                >
                                    <svg v-if="action.checked" class="w-3 h-3 text-white absolute top-0.5 left-0.5" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                                        <path d="M13.5 4.5L6.5 11.5L2.5 7.5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                    </svg>
                                </div>
                                <span class="ml-2" :class="{
                                    'text-gray-600': !action.checked,
                                    'text-primary': action.checked
                                }">{{ action.name }}</span>
                            </div>
                        </div>
                        <!-- 递归子节点 -->
                        <template v-else>
                            <PermissionTree :nodes="node.children" @update:checked="handleCheck" />
                        </template>
                    </div>
                </div>
            </template>
        </div>
    `
})

// 权限数据
const permissions = reactive<PermissionNode[]>([
    {
        id: 1,
        name: '工作台',
        type: 1,
        checked: false,
        indeterminate: false
    },
    {
        id: 2,
        name: '系统管理',
        type: 1,
        checked: false,
        indeterminate: false,
        children: [
            {
                id: 21,
                name: '权限管理',
                type: 2,
                checked: false,
                indeterminate: false,
                children: [
                    {
                        id: 211,
                        name: '角色管理',
                        type: 2,
                        checked: false,
                        indeterminate: false,
                        children: [
                            {
                                id: 2111,
                                name: '新增',
                                type: 3,
                                checked: false
                            },
                            {
                                id: 2112,
                                name: '编辑',
                                type: 3,
                                checked: false
                            },
                            {
                                id: 2113,
                                name: '删除',
                                type: 3,
                                checked: false
                            }
                        ]
                    },
                    {
                        id: 212,
                        name: '管理员',
                        type: 2,
                        checked: false,
                        indeterminate: false,
                        children: [
                            {
                                id: 2121,
                                name: '新增',
                                type: 3,
                                checked: false
                            },
                            {
                                id: 2122,
                                name: '编辑',
                                type: 3,
                                checked: false
                            },
                            {
                                id: 2123,
                                name: '删除',
                                type: 3,
                                checked: false
                            }
                        ]
                    }
                ]
            },
            {
                id: 22,
                name: '系统设置',
                type: 2,
                checked: false,
                indeterminate: false,
                children: [
                    {
                        id: 221,
                        name: '基础设置',
                        type: 3,
                        checked: false
                    },
                    {
                        id: 222,
                        name: '安全设置',
                        type: 3,
                        checked: false
                    }
                ]
            }
        ]
    }
])

// 处理权限更新
const handlePermissionUpdate = (node: PermissionNode) => {
    console.log('权限更新:', node.name, node.checked)
}
</script>

<style scoped>
.bg-primary {
    background-color: #2563eb;
}
.border-primary {
    border-color: #2563eb;
}
.text-primary {
    color: #2563eb;
}
.bg-indeterminate {
    background-color: #e5e7eb;
    position: relative;
}
.bg-indeterminate::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 8px;
    height: 2px;
    background-color: #6b7280;
}
</style>